package org.wso2.carbon.registry.custom.dia.ui.utils;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.wso2.carbon.registry.common.ui.UIException;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.resource.ui.clients.CustomUIServiceClient;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.ServletConfig; 
import org.wso2.carbon.registry.custom.dia.ui.clients.TopicServiceClient;

public class AddDocumentUtil {
 
    private static final Log log = LogFactory.getLog(AddDocumentUtil.class);

    private TopicServiceClient client;
    //TODO CHeck a solution for the redirection in dia_add_handler_ajaxprocessor.jsp
    //TODO do GET and SAVE docUtil  
    
    public AddDocumentUtil(ServletConfig config, HttpSession session
            ) throws UIException {
        try {
            client = new TopicServiceClient(config, session);
        } catch (RegistryException e) {
             String msg = "Failed to add documentation. " + e.getMessage();
            log.error(msg, e);
            throw new UIException(msg, e);
        }
    }

    public void addDocumentBean(
            HttpServletRequest request, ServletConfig config, HttpSession session
            ) throws UIException {

        try {
            CustomUIServiceClient customUIServiceClient =
                    new CustomUIServiceClient(config, session);
 
            String parentPath = request.getParameter("parentPath");
            String title = request.getParameter("diaTitle");
            String summary = request.getParameter("diaSummary");
            String link = request.getParameter("diaLink");
            
            String product = request.getParameter("product");
            String productRelease = request.getParameter("productRelease");
            String carbonPlatform = request.getParameter("carbonPlatform");
            String jdkPlatform = request.getParameter("jdkPlatform");

            String resourceName;
            if(title !=null){
                 resourceName = generateResName(title);
            } else{
                return;
            }
            //TODO implement adding several related docs and tags.
            //TODO do Form Validation
            //TODO add carbon version
            
            /*Structure of the OM
             *
             * <document>
                  <title>xxx</title>
                  <summary>xxxx</summary>
                  <externalLink>http://xxx</externalLink>
                  <relatedProduct>
                    <name>xxx</name>
                    <release>x.x.x</release>
                  </relatedProduct>
                  <environment>
                    <carbonPlatform>x.x.x</carbonPlatform>
                    <jdk>x.x</jdk>
                  </environment>
             * </document>
             */
            
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMElement document = fac.createOMElement("document", null);
            OMElement titleElement = fac.createOMElement("title", null);
                titleElement.setText(title);
            OMElement summaryElement = fac.createOMElement("summary", null);
                summaryElement.setText(summary);
            OMElement linkElement = fac.createOMElement("externalLink", null);
                linkElement.setText(link);

            OMElement relatedProduct = fac.createOMElement("relatedProduct", null);
                OMElement productElement = fac.createOMElement("product", null);
                    productElement.setText(product);
                OMElement releaseElement = fac.createOMElement("release", null);
                    releaseElement.setText(productRelease);
            relatedProduct.addChild(productElement);
            relatedProduct.addChild(releaseElement);

            OMElement environment = fac.createOMElement("environment", null);
                OMElement carbonPlatformElement = fac.createOMElement("carbonPlatform", null);
                    carbonPlatformElement.setText(carbonPlatform);
                OMElement jdkElement = fac.createOMElement("jdk", null);
                    jdkElement.setText(jdkPlatform);
            environment.addChild(carbonPlatformElement);
            environment.addChild(jdkElement);

            document.addChild(titleElement);
            document.addChild(summaryElement);
            document.addChild(linkElement);
            document.addChild(relatedProduct);
            document.addChild(environment);

            String content = document.toString(); 

            customUIServiceClient.addTextContent(
                    parentPath, resourceName, "dia", null, content);

        } catch (Exception e) {
            String msg = "Failed to add documentation. " + e.getMessage();
            log.error(msg, e);
            throw new UIException(msg, e);
        }
    }
    public void addAssociations(
        HttpServletRequest request,  ServletConfig config, HttpSession session
        ) throws UIException{
        
        String sPath = getSourcePath(request);
        int numOfAsso = Integer.parseInt(request.getParameter("numOfAsso"));
        
        for(int i=0;i<=numOfAsso;i++){
            String assoType = "related-document";//request.getParameter("aType"+i);
            String assoPath = request.getParameter("aPath"+i);
            client.addAssociation(sPath, assoPath, assoType);
        }
    } 

    /**
     * Applies tags belongs to the current document by extracting tag details
     * from the diaAddFrom in dia_add_document.jsp. tags will be in Comma
     * separated String. So, first the tags are extracted and they are applied
     * using TopicServiceClient.
     *
     * @throws RegistryException
     *
     */
    public void applyTags(
            HttpServletRequest request,  ServletConfig config, HttpSession session
            ) throws UIException{

        try{
            String sPath = getSourcePath(request);

            String tags = request.getParameter("diaTags");
            Scanner sc = new Scanner(tags);
            sc.useDelimiter(",");

            String tag;
            while(sc.hasNext()){
                tag = sc.next();
                tag.trim();
                client.applyTag(sPath, tag);
            }
        }catch(Exception e){
            String msg = "Failed while adding tags. " + e.getMessage();
            log.error(msg, e);
            throw new UIException(msg, e);
        }
    }

    public String getSourcePath(HttpServletRequest request){
            String parentPath = request.getParameter("parentPath");
            String title = request.getParameter("diaTitle");
            String resourceName =  generateResName(title);
            String sPath;

            if(!parentPath.equals("/") ){
                 sPath = parentPath+"/"+resourceName;
            } else{
                sPath = parentPath+resourceName;
            }

            return sPath;
    } 
    private String generateResName(String title) {
      String name = title;

      name = name.replaceAll("[\\._\\s-]+", "-");
      Pattern p = Pattern.compile("[^A-Za-z0-9\\._\\-]+");
      Matcher m = p.matcher(name);
      StringBuffer sb = new StringBuffer();
      boolean result = m.find();

      while(result) {
         m.appendReplacement(sb, "");
         result = m.find();
      }

      // Add the last segment of input to the new String
      m.appendTail(sb);

      name = sb.toString(); 

      return name;
    }
 

}
